<template>
  <div class="map-container">
    <div ref="mapContainer" class="map-content" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { VehicleMonitoringData } from "@/api/LogisticsManagement/vehicleMonitoringData";
import router from "@/router";
import { getToken } from "@/utils/auth";

// 父组件传递当前位置
const props = defineProps<{
  //多辆车
  driverList?: string;
  driver?: VehicleMonitoringData & { targetName?: string; targetPosition?: Position };
}>();

let infoWindow: any = null;
// 类型定义
interface Position {
  lng: number;
  lat: number;
  speed?: number;
  timestamp: string;
}

//告诉父级车速，锁状态，温度等信息给父组件
const emit = defineEmits<{
  (
    e: "getDriverInfo",
    driver: VehicleMonitoringData & { targetName?: string; currentName?: string }
  ): void;
  (e: "getPositionFailed", flag: boolean): void;
}>();

const mapContainer = ref<HTMLElement>();
let AMap: any;
let map: any;
let marker: any;

let moveAnimation: any;
let driving: any;
// 车辆状态
const currentPosition = ref<Position>({
  lng: 116.478935,
  lat: 39.997761,
  timestamp: "",
});
const targetPosition = ref<Position>({
  lng: 116.478935,
  lat: 39.997761,
  timestamp: "",
});
const routePath = ref<Position[]>([]);

// 在script中定义可配置的SVG
const generateTruckIcon = (color = "#409EFF", size = 48, rotate = 0) => {
  const svg = `
    <svg width="${size}" height="${size}" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" transform="rotate(${rotate})">
      <path d="M26 12H22V8H28L26 12Z" fill="${color}"/>
      <path d="M29 14H22V19H30L29 14Z" fill="${color}"/>
      <path d="M4 6C4 5.44772 4.44772 5 5 5H20C20.5523 5 21 5.44772 21 6V19H4V6Z" fill="${color}"/>
      <circle cx="9" cy="22" r="3" fill="#666"/>
      <circle cx="23" cy="22" r="3" fill="#666"/>
      <path d="M4 19H30V23H4V19Z" fill="${color}"/>
    </svg>
  `;
  return `data:image/svg+xml;base64,${btoa(svg)}`;
};
//根据目标地址获取经纬度
const getTargetPosition = (name?: string) => {
  if (!name) return Promise.reject("车辆没有目标地址");
  return new Promise((resolve, reject) => {
    AMap.plugin("AMap.PlaceSearch", function () {
      const placeSearch = new AMap.PlaceSearch();
      placeSearch.search(name, (status: any, result: any) => {
        console.log(result, "目标result", status, ",status");
        if (result.poiList.pois.length > 0) {
          const lng = result.poiList.pois[0].location.lng;
          const lat = result.poiList.pois[0].location.lat;
          resolve({ lng, lat, timestamp: Date.now() });
        } else {
          reject("未找到目标地址");
        }
      });
    });
  });
};

//根据经纬度获取地址名

//信息模板
const infoTemplate = (
  driver: {
    latitude: string;
    lockStatus: string;
    longitude: string;
    speed: string;
    temperature: string;
    timestamp: string;
    vehicleId: string;
  } & { targetName?: string; currentName?: string }
) => {
  return `
      <div style="width=300px;height=300px;">
        <h3>${driver?.vehicleId}</h3>
        <p>锁:${driver?.lockStatus ? "开" : "关"}</p>
        <p>车速：${driver?.speed}km/h</p>
      </div>
    `;
};
// 创建信息窗口
const createInfoWindow = async (
  position: Position,
  driver: {
    latitude: string;
    lockStatus: string;
    longitude: string;
    speed: string;
    temperature: string;
    timestamp: string;
    vehicleId: string;
  } & { targetName?: string }
) => {
  if (infoWindow) {
    infoWindow.close();
  }
  infoWindow = new AMap.InfoWindow({
    content: infoTemplate(driver),
    offset: new AMap.Pixel(0, -40), // 调整信息窗口位置
  });
  infoWindow.open(map, new AMap.LngLat(position.lng, position.lat));
};

// 初始化地图
const initMap = async () => {
  try {
    AMap = await AMapLoader.load({
      key: "b3a23b0c4cb9cf80129be0d1bc53c900",
      version: "2.0",
      plugins: ["AMap.Driving", "AMap.MoveAnimation"], // 确保加载必要插件
    });

    map = new AMap.Map(mapContainer.value, {
      viewMode: "3D",
      zoom: 13,
      center: [currentPosition.value.lng, currentPosition.value.lat],
      resizeEnable: true,
    });
    nextTick(() => {
      connectWebSocket();
    });
  } catch (error) {
    console.error("地图初始化失败:", error);
  }
};
//显示多辆车位置
const showMapInfoAll = async (plateList: any) => {
  console.log(plateList, "plateList");
  if (!(plateList && plateList.length > 0)) return;
  plateList.forEach(
    (driver: {
      latitude: string;
      lockStatus: string;
      longitude: string;
      speed: string;
      temperature: string;
      timestamp: string;
      vehicleId: string;
    }) => {
      console.log(driver, "driver");

      if (!(driver.latitude || driver.longitude)) return;
      const currentPosition: Position = {
        lng: parseFloat(driver.longitude),
        lat: parseFloat(driver.latitude),
        timestamp: driver.timestamp,
      };
      //显示多辆车
      console.log(currentPosition, "currentPosition");

      AMap.plugin("AMap.MoveAnimation", function () {
        const marker = new AMap.Marker({
          map: map,
          position: [currentPosition.lng, currentPosition.lat],
          icon: generateTruckIcon(),
          offset: new AMap.Pixel(-24, -48),
        });
        marker.on("click", () => {
          console.log("点击了货车");
          createInfoWindow(new AMap.LngLat(currentPosition.lng, currentPosition.lat), driver);
        });
      });
    }
  );
};

//显示一辆车轨迹
const showMapInfoOne = async (
  driver: {
    latitude: string;
    lockStatus: string;
    longitude: string;
    speed: string;
    temperature: string;
    timestamp: string;
    vehicleId: string;
  } & { targetName?: string }
) => {
  if (driver.latitude == undefined) return;
  driver.targetName = props.driver?.targetName;
  console.log(props.driver?.targetName, "driver");

  const currentPosition: Position = {
    lng: parseFloat(driver.longitude),
    lat: parseFloat(driver.latitude),
    timestamp: driver.timestamp,
  };

  //设置地图中心和缩放

  //将小车绘制
  const marker = new AMap.Marker({
    map: map,
    position: [currentPosition.lng, currentPosition.lat],
    icon: generateTruckIcon(),
    offset: new AMap.Pixel(-24, -48),
  });
  //点击小车绘制信息窗口
  marker.on("click", () => {
    console.log("点击了货车");
    createInfoWindow(new AMap.LngLat(currentPosition.lng, currentPosition.lat), driver);
  });
  AMap.plugin("AMap.Driving", function () {
    driving = new AMap.Driving({
      map: map,
      policy: AMap.DrivingPolicy.LEAST_TIME,
      hideMarkers: true,
    });
  });
  if (!props.driver?.targetName) return;
  getTargetPosition(props.driver?.targetName)
    .then((targetPosition: any) => {
      console.log(props.driver?.targetName, "targetName");
      updateRoute(currentPosition, targetPosition);
    })
    .catch((error) => {
      console.log(props.driver?.targetName, "targetName");
      console.error("获取目标位置失败:", error);
      //提示用户目标地址未找到
      // ElMessage.error(error);
    });
};

//根据父组件传递信息显示不同地图信息
const showMapInfo = async () => {
  if (props.driverList == "all") {
    sendWebSocket("plateList", "");
    sendInterval = setInterval(() => {
      sendWebSocket("plateList", "");
    }, 5000);

    // plateList.value?.forEach((driver: any) => {
    //   console.log(driver, "driver");

    //   if (!driver.coordinates) return;
    //   const currentPosition: Position = {
    //     lng: parseFloat(driver.coordinates?.split(",")[0] || "0"),
    //     lat: parseFloat(driver.coordinates?.split(",")[1] || "0"),
    //     timestamp: Date.now(),
    //   };
    //   //显示多辆车
    //   console.log(currentPosition, "currentPosition");
    //   map.setCenter([currentPosition.lng, currentPosition.lat]);
    //   AMap.plugin("AMap.MoveAnimation", function () {
    //     const marker = new AMap.Marker({
    //       map: map,
    //       position: [currentPosition.lng, currentPosition.lat],
    //       icon: generateTruckIcon(),
    //       offset: new AMap.Pixel(-24, -48),
    //     });
    //     marker.on("click", () => {
    //       console.log("点击了货车");
    //       createInfoWindow(new AMap.LngLat(currentPosition.lng, currentPosition.lat), driver);
    //     });
    //   });
    // });
  } else if (props.driver) {
    sendWebSocket("plateList", props.driver?.licensePlate);
    sendInterval = setInterval(() => {
      sendWebSocket("plateList", props.driver?.licensePlate);
    }, 5000);

    // const currentPosition: Position = {
    //   lng: parseFloat(props.driver.coordinates.split(",")[0]),
    //   lat: parseFloat(props.driver.coordinates.split(",")[1]),
    //   timestamp: Date.now(),
    // };

    // //设置地图中心和缩放
    // map.setCenter([currentPosition.lng, currentPosition.lat]);
    // map.setZoom(5);
    // //将小车绘制
    // const marker = new AMap.Marker({
    //   map: map,
    //   position: [currentPosition.lng, currentPosition.lat],
    //   icon: generateTruckIcon(),
    //   offset: new AMap.Pixel(-24, -48),
    // });
    // //点击小车绘制信息窗口
    // marker.on("click", () => {
    //   console.log("点击了货车");
    //   createInfoWindow(
    //     new AMap.LngLat(currentPosition.lng, currentPosition.lat),
    //     props.driver as VehicleMonitoringData & { targetName?: string; targetPosition?: Position }
    //   );
    // });
    // AMap.plugin("AMap.Driving", function () {
    //   driving = new AMap.Driving({
    //     map: map,
    //     policy: AMap.DrivingPolicy.LEAST_TIME,
    //     hideMarkers: true,
    //   });
    // });
    // getTargetPosition(props.driver?.targetName)
    //   .then((targetPosition: any) => {
    //     console.log(props.driver?.targetName, "targetName");
    //     updateRoute(currentPosition, targetPosition);
    //   })
    //   .catch((error) => {
    //     console.log(props.driver?.targetName, "targetName");
    //     console.error("获取目标位置失败:", error);
    //     //提示用户目标地址未找到
    //     // ElMessage.error(error);
    //   });

    //规划路线
  } else {
    console.log(3333);
  }
};

// 路径规划（带缓存）
const calculateRoute = async (start: Position, end: Position): Promise<Position[]> => {
  return new Promise((resolve) => {
    driving.clear();
    console.log("开始路径规划");
    var endIcon = new AMap.Icon({
      size: new AMap.Size(25, 34),
      image: "//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png",
      imageSize: new AMap.Size(135, 40),
      imageOffset: new AMap.Pixel(-95, -3),
    });
    driving.search(
      new AMap.LngLat(start.lng, start.lat),
      new AMap.LngLat(end.lng, end.lat),
      function (status: any, result: any) {
        console.log("result", result);
        if (status === "complete") {
          console.log("绘制驾车路线完成");
          const endMarker = new AMap.Marker({
            map: map,
            position: [end.lng, end.lat],
            icon: endIcon,
            offset: new AMap.Pixel(-13, -30),
          });
          const path = result.routes[0].steps
            .flatMap((step: any) => step.path)
            .map((p: any) => ({ lng: p.lng, lat: p.lat }));
          console.log("路径点数据:", path);
          resolve(path);

          // map.value.setCenter(currentPosition);
        } else {
          console.log("获取驾车数据失败：" + result);
          resolve([]);
        }
      }
    );
  });
};
// 平滑移动动画
const animateMovement = (path: Position[]) => {
  if (!moveAnimation) return;

  const convertedPath = path.map((p) => new AMap.LngLat(p.lng, p.lat));

  moveAnimation.stop();
  moveAnimation.moveAlong(convertedPath, {
    duration: path.length * 50, // 动态计算持续时间
    autoRotation: true,
    callback: () => {
      console.log("移动完成");
    },
  });

  // 视图跟随
  map.setFitView([marker], { padding: [50, 50, 50, 50] });
};

// 路径偏离检测
const shouldRepath = (newPos: Position) => {
  if (!routePath.value.length) return true;

  const lastPoint = routePath.value[routePath.value.length - 1];
  const distance = AMap.GeometryUtil.distance(
    new AMap.LngLat(newPos.lng, newPos.lat),
    new AMap.LngLat(lastPoint.lng, lastPoint.lat)
  );

  return distance > 50; // 50米阈值
};

// 更新路线
const updateRoute = async (currentPosition: Position, targetPosition: Position) => {
  if (!currentPosition) return;

  const newPath = await calculateRoute(currentPosition, targetPosition);
  console.log("newPath", newPath);
  if (newPath && newPath.length) {
    routePath.value = newPath;
    animateMovement(newPath);
  }
};

// 监听当前位置变化
watch(currentPosition.value, (newVal) => {
  if (newVal) updateRoute(newVal, targetPosition.value);
});

//设置最大重连次数
const maxReconnectAttempts = 1;
let reconnectAttempts = ref(0);
let healthCheckInterval: NodeJS.Timeout; // 健康检查定时器
let pingInterval: NodeJS.Timeout; //发送ping定时器
let reconnectTimeout: NodeJS.Timeout; // 重连定时器
const reconnect = () => {
  if (reconnectAttempts.value <= maxReconnectAttempts) {
    reconnectTimeout = setTimeout(() => {
      reconnect();
      reconnectAttempts.value++;
      console.log("尝试重连", `重连次数${reconnectAttempts.value}`);
    }, 5000);
  } else {
    console.error("达到最大重连次数，停止重连。");
  }
};

//获取token
const websocketPoint = import.meta.env.VITE_APP_WS_ENDPOINT;
const ws = ref<WebSocket | null>(null);

const connectWebSocket = async () => {
  try {
    ws.value = new WebSocket(`${websocketPoint}/vehicle/location?token=${getToken()}`);

    ws.value.onopen = () => {
      console.log("WebSocket已连接");
      sendWebSocket("ping");

      pingInterval = setInterval(() => {
        sendWebSocket("ping");
      }, 300000);
      showMapInfo();
    };

    ws.value.onmessage = async (event) => {
      const data = JSON.parse(event.data);
      console.log(data, "websocket消息");

      if (data.type == "unLogin") {
        //返回登录页
        return router.push("/login");
      }
      if (data.type == "close") {
        return ws.value?.close();
      }
      if (data.type == "plateAll") {
        console.log(data.data, "plateList数据");

        showMapInfoAll(data.data);
      }
      if (data.type == "plate") {
        if (data.data.longitude == null || data.data.latitude == null) {
          emit("getPositionFailed", false);
          return;
        }
        map.setCenter([data.data.longitude, data.data.latitude]);

        showMapInfoOne(data.data);
        emit("getDriverInfo", data.data);
      }
    };
    ws.value.onclose = (event) => {
      console.log("断开了", event);
      ws.value = null;
      reconnect();
    };
    ws.value.onerror = (event) => {
      ws.value = null;
      console.log("WebSocket连接失败");
    };
  } catch (error) {}
};
//发送消息定时器
let sendInterval: NodeJS.Timeout;

const sendWebSocket = (type: string, plateList?: string) => {
  if (ws.value && ws.value.readyState === WebSocket.OPEN) {
    ws.value.send(JSON.stringify({ type, plateList }));
  } else {
    console.warn("WebSocket not ready, message not sent");
  }
};

const disconnectWebSocket = () => {
  clearInterval(pingInterval);
  clearInterval(sendInterval);
  clearTimeout(reconnectTimeout);
  reconnectAttempts.value = 0;

  sendWebSocket("close");
  if (ws.value) {
    ws.value.close();
    ws.value.onclose = () => {
      console.log("WebSocket断开");
      ws.value = null;
    };
  }
};

onMounted(async () => {
  console.log(props, "props.plateList");

  await initMap();
});

// 组件卸载时销毁地图
onUnmounted(() => {
  if (map) map.destroy();
  disconnectWebSocket();
});
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 100%;
  position: relative; /* 添加相对定位 */
}

.map-content {
  width: 100%;
  height: 100%;
  min-height: 400px; /* 添加最小高度 */
}

:deep(.amap-marker-label) {
  border: none;
  background-color: transparent;
  color: #333;
  font-size: 12px;
  font-weight: bold;
  text-shadow: 1px 1px 1px #fff;
}

:deep(.amap-info-content) {
  padding: 8px;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  font-size: 12px;
  line-height: 1.5;
}

.marker {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 12px;
}

.start-marker {
  background-color: #67c23a;
}

.end-marker {
  background-color: #f56c6c;
}
</style>
